package com.baymax.test.scene.internal.key

import android.util.Log
import android.view.KeyEvent
import com.baymax.lib.key.KeySession
import com.baymax.lib.key.KeyTransformer
import io.reactivex.Completable
import io.reactivex.disposables.Disposable
import io.reactivex.disposables.Disposables
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference

/**
 * 自定义按键处理器
 */


class KeyCodeCombinationProcessor(
    private val keyTransformer: KeyTransformer,
) {

    private val TAG = "KeyCodeCombination"

    private val keySession = KeySession.newSession(
        keyTransformer.config,
        keyTransformer::onPickStart,
        keyTransformer::onPickEnd
    )

    private var delayCheck: Disposable = Disposables.disposed()

    fun sendKey(keyEvent: KeyEvent) {
        when (doSend(keyEvent)) {
            State.Continue -> {
                //todo 未输入等待超时
                //匹配成功
                check(keyEvent)
                this.delayCheck.dispose()
                if (!keySession.isDisposed) {
                    this.delayCheck =
                        Completable.timer(keyTransformer.config.inputDuration, TimeUnit.MILLISECONDS)
                            .subscribe {
                                Log.i(TAG, "delay complete")
                                if (!keySession.isDisposed) {
                                    keySession.cancel(keyEvent)
                                }
                            }
                }
            }

            State.Canceled -> {
                delayCheck.dispose()
                keySession.cancel(keyEvent)
            }

            else -> {}
        }
    }

    private fun check(keyEvent: KeyEvent) {
        if (!keySession.isDisposed && keyEvent != KeySession.EMPTY) {
            val checkComplete = keyTransformer.checkComplete(keySession)
            if (checkComplete != null) {
                //直接满足条件
                keyTransformer.onPickSuccess(keySession ,checkComplete)
                keySession.complete(keyEvent)
            }
        }

    }


    private fun doSend(keyEvent: KeyEvent): State {

        if (!keyTransformer.enable()) {
            Log.w(TAG, "disable key combination")
            return State.Canceled

        }
        if (!keyTransformer.filter(keyEvent)) {
            Log.w(
                TAG,
                String.format("key filter ignore %s", KeyEvent.keyCodeToString(keyEvent.keyCode))
            )
            return State.Ignore
        }

        if (!keyTransformer.except(keyEvent)) {
            Log.w(
                TAG,
                String.format("key except fail %s", KeyEvent.keyCodeToString(keyEvent.keyCode))
            )
            return State.Canceled
        }
        println(keyEvent)
        //按键通过
        val disposed = keySession.isDisposed
        if (disposed) {
            //是否在上次的间隔区间内
            val out = keySession.outThrottle(keyEvent)
            if (out) {
                //重新开启
                keySession.start(keyEvent)
            } else {
                //ignore
                Log.w(TAG, "out ignore")
                return State.Ignore
            }
        } else {
            val ok = keySession.continueKeyEvent(keyEvent)
            if (!ok) {
                return State.Canceled
            }
            keyTransformer.onPickContinue(keySession)
        }

        return State.Continue
    }

    sealed interface State {
        object Continue : State
        object Ignore : State
        object Canceled : State

    }

    abstract class Reference(private val event: KeyEvent) : AtomicReference<KeyEvent>(event),
        Disposable {

        abstract fun onDisposed(keyEvent: KeyEvent)

        override fun dispose() {
            var current = get();
            if (current != KeySession.EMPTY) {
                current = getAndSet(KeySession.EMPTY)
                if (current != KeySession.EMPTY) {
                    onDisposed(current)
                }
            }
        }

        override fun isDisposed(): Boolean = get() == KeySession.EMPTY
    }
}

